#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define MAX_PATH_LENGTH (80)
#define NUMSYMB (100)
#define DMAX (8)
#define MAXNUM_MIDI (50)
#define NUM_GROOVES (19)			
#define ROOT (1)
#define LEAF (0)
#define MAX_DEPTH (25)
#define NUM_GROOVE_TEMPLATES NUM_GROOVES
#include "PSTHeader.h"
#include "subsequence.h"
typedef struct Groove
{
       char note[MAXNUM_MIDI];
       char dur[MAXNUM_MIDI];
       char velocity[MAXNUM_MIDI];
       int length;
} Groove;
/*
typedef struct GrooveInfo
{
	float GrooveEntropy;
	float meanIOI;
	float intensity;
} GrooveInfo;
*/

int GrooveClassify(Groove*, Groove*, int);
//GrooveInfo* GrooveExtractInfo(Groove* groove);
int getDurName(int x);
int getNoteName(int x);
int getNoteName(int x){
	return(x);
}
int getDurName(int x){
	return(x+48);
}
int GrooveClassify(Groove* groove, Groove* gTemp, int NumTemplates){
	int i;
	float big = 0;
	int bigIndex = 1;
	float comp[NUM_GROOVES];
	Groove *ptr;
	ptr = gTemp;
	for(i=0;i<NumTemplates;i++){
//		comp[i] = ((float)(lcs_length(ptr->note, groove->note) + lcs_length(ptr->dur,groove->dur))/(2.0*(float)(groove->length)));
		comp[i] = ((float)(lcs_length(ptr->note, groove->note)))/((float)(groove->length) + (float)(ptr->length));
		if (comp[i] > big){
			big = comp[i];
			bigIndex = i+1;
		}
		ptr++;
//		std::cout<<i+1<<"\t"<<comp[i]<<std::endl;
	}
	return(bigIndex);
}

void grooveSort(int size, float arrVal[], int arrInd[])
{
	// A simple bubble sort for groove Sorting
	int i, j, tempInd; 
	float temp;
	
	for (i = (size - 1); i > 0; i--)
	{
		for (j = 1; j <= i; j++)
		{
			if (arrVal[j-1] < arrVal[j])	// Descending order sort
			{
				// Sort values
				temp = arrVal[j-1];
				arrVal[j-1] = arrVal[j];
				arrVal[j] = temp;
				// Sort Indices
				tempInd = arrInd[j-1];
				arrInd[j-1] = arrInd[j];
				arrInd[j] = tempInd;
			}
		}
	}
}

int grooveSample(int size, float arrVal[],int arrInd[]){
// Assumes that the arrVal is sorted and groove indices are in arrInd 	
	int i, grooveNum;
	float rnd = (float)(rand())/(float)(RAND_MAX);
	for(int i=0; i<size; i++) {
		if(rnd < arrVal[i])
			return arrInd[i]+1;
		rnd -= arrVal[i];
	}
	printf("You should never come here");
}

// Do a MAP groove prediction
int findMAPGrooveUnsorted(int size, float arrVal[], int arrInd[]){
	// The array is unsorted here
	int i, bigInd = 0;
	float bigVal = 0.0;
	for(i=0;i<size;i++){
		if(arrVal[i] > bigVal){
			bigVal = arrVal[i];
			bigInd = arrInd[i];
		}
	}
	return (bigInd + 1);
}

/*
 GrooveInfo* GrooveExtractInfo(Groove groove){
	int k;
	GrooveInfo info;
	double IOI[MAXNUM_MIDI];
	double velo[MAXNUM_MIDI];
	for(k=0;k<groove.length;k++){
		IOI[k] = (double)(groove.dur[k]);
		velo[k] = (double)(groove.velocity[k]);
	}
	IOI_hist_entropy(IOI, groove.length, MAXNUM_MIDI);
}*/